home *** CD-ROM | disk | FTP | other *** search
- #include <cmath>
- #include <cstdio>
- #include <cstring>
- #include <memory>
-
-
- #include <LowMem.h>
- #include <QDOffscreen.h>
- #include <Quickdraw.h>
- #include <Retrace.h>
-
-
- #include <A4Stuff.h>
-
-
- // hash is not fully implemented
- #define HASH 0
-
- // enable to get fps at the end
- #define PROFILE 0
-
- // as well as being ugly, scale is broken
- #define SCALE 0
-
-
- #if VECTOR
- #include <altivec.h>
-
- typedef union Float4
- {
- float floats[4];
- vector float vec;
- } Float4;
- #endif
-
-
- static pascal void Copier(VBLTaskPtr pTask);
- static void DrawRotatedImage(float rotation, bool drawCursor);
-
- #if 0
- // not used, but cool
- static void PlotCursor(Cursor *pCurs);
- #endif
-
- #if HASH
- void CheckHashes(short *pFirst, short *pLast);
- #endif
-
- void ResetScreen();
-
- void SetOn();
- void SetOff();
-
-
- void UpdateGlobals();
-
-
-
- Ptr g_pBase;
- unsigned long g_ulHeight;
- unsigned long g_ulWidth;
- unsigned long g_ulCopySize;
- unsigned long g_ulRowBytes;
- Ptr g_pFakeBase;
- short g_nDepth;
-
- bool g_bOn = false;
- bool g_bDone = false;
-
- bool g_bUpdating = false;
-
-
- #if PROFILE
- unsigned long g_ulTicksElapsed = 0UL;
- unsigned long g_ulFrameCount = 0UL;
- #endif
-
-
- PixMapHandle g_hPM;
-
-
- #if HASH
- unsigned long *g_pHashes;
- #endif
-
-
- float g_dRotation = 0.0;
- extern const double_t pi;
-
-
- class Mgr
- {
- public:
- inline Mgr()
- {
- SetZone(SystemZone());
-
- m_sVBL.qLink = NULL;
- m_sVBL.qType = vType;
- m_sVBL.vblAddr = NewVBLUPP(Copier);
- m_sVBL.vblCount = 1;
- m_sVBL.vblPhase = 0;
-
- VInstall((QElemPtr)&m_sVBL);
-
- SetZone(ApplicationZone());
- }
-
- inline ~Mgr()
- {
- SetZone(SystemZone());
- VRemove((QElemPtr)&m_sVBL);
- SetZone(ApplicationZone());
- SetOff();
- }
-
- private:
- VBLTask m_sVBL;
- };
-
-
- int main()
- {
- UpdateGlobals();
-
- char *pPtr = new char[g_ulCopySize];
- g_pFakeBase = pPtr;
-
- #if HASH
- g_pHashes = new unsigned long[g_ulHeight];
- std::memset(g_pHashes, 0, g_ulHeight * sizeof(unsigned long));
- #endif
-
- unsigned long ulTicks = TickCount();
-
- std::auto_ptr<Mgr> apMgr = std::auto_ptr<Mgr>(new Mgr);
-
- do
- {
- // std::printf(".");
-
- EventRecord event;
- WaitNextEvent(0, &event, 60, NULL);
-
- // KeyMap keys;
- // GetKeys(keys);
-
- // g_bDone = TickCount() - ulTicks > 60 * 30;//(((keys[1] >> 15) & 0x1) != 0 && ((keys[1] >> 23) & 0x1) != 0);
- }
- while(!g_bDone);
-
- delete(apMgr.release());
-
-
- #if PROFILE
- Str255 strlDebug;
- strlDebug[0] = std::snprintf((char *)&strlDebug[1], 255, "\n%lu frames in %lu ticks (%f fps)", g_ulFrameCount, g_ulTicksElapsed, (float)g_ulFrameCount * 60.0 / g_ulTicksElapsed);
- DebugStr(strlDebug);
- #endif
-
-
- return 0;
- }
-
-
- // constants
- #define kRadiansPerRevolution (2.0 * pi)
-
- #if SCALE
- #define kXScaleMin ((float)g_ulHeight / (float)g_ulWidth)
- #define kXScaleMax (1.0)
-
- #define kYScaleMin (1.0)
- #define kYScaleMax ((float)g_ulWidth / (float)g_ulHeight)
- #endif
-
- #define kGranularity (bCapsLock ? 100.0 : 300.0)
-
-
- static pascal void Copier(VBLTaskPtr pTask)
- {
- static unsigned long ulLast = 0UL;
-
- if(TickCount() - ulLast >= 3)
- {
- ulLast = TickCount();
-
- KeyMap keyMap;
- GetKeys(keyMap);
-
- bool bEsc = (keyMap[1] & (0x1 << 13)) != 0;
- bool bOpt = (keyMap[1] & (0x1 << 2)) != 0;
- bool bCtrl = (keyMap[1] & (0x1 << 3)) != 0;
- bool bCmd = (keyMap[1] & (0x1 << 15)) != 0;
- bool bShift = (keyMap[1] & 0x1) != 0;
- bool bCapsLock = (keyMap[1] & (0x1 << 1)) != 0;
-
- if(bCmd && bEsc)
- {
- g_bDone = true;
- }
-
- if(bOpt) // opt
- {
- if(bCmd) // cmd
- {
- g_dRotation -= kRadiansPerRevolution / kGranularity;
- }
- else
- {
- g_dRotation += kRadiansPerRevolution / kGranularity;
- }
- }
-
- if(bCtrl && bEsc)
- {
- if(bShift)
- {
- g_dRotation = pi;
- }
- else
- {
- g_dRotation = 0.0;
- }
- }
-
- static bool sLastWasZero = true;
-
- if(g_bUpdating == false)
- {
- // special case for second and later 0s
- if(g_dRotation == 0.0 && sLastWasZero)
- {
- SetOff();
- }
- else
- {
- SetOn();
-
- sLastWasZero = false;
- if(g_dRotation == 0.0)
- {
- sLastWasZero = true;
- }
-
- #if PROFILE
- g_ulFrameCount++;
- g_ulTicksElapsed -= TickCount();
- #endif
- DrawRotatedImage(g_dRotation, true);
- #if PROFILE
- g_ulTicksElapsed += TickCount();
- #endif
- }
- }
- }
- pTask->vblCount = 1;
- }
-
-
- #define InCursor(x, y) (((y) >= cursTop && (y) < cursBottom) && ((x) >= cursLeft && (x) < cursRight))
- #define InCursorMaskRel(x, y) (sCurs.mask[(y)] & (1 << (16 - (x) - 1)))
- #define InCursorMask(x, y) InCursorMaskRel((x) - cursLeft, (y) - cursTop)
-
- #define CursorDataIs1Rel(x, y) (sCurs.data[(y)] & (1 << (16 - (x) - 1)))
- #define CursorDataIs1(x, y) CursorDataIs1Rel((x) - cursLeft, (y) - cursTop)
-
-
- #if VECTOR
- #define XINCREMENT 4
- #else
- #define XINCREMENT 1
- #endif
-
-
- #define XSRC(n) x_src ## n
- #define YSRC(n) y_src ## n
- #define DST(n) dst ## n
-
- #define SetPixel(num) \
- { \
- if(XSRC(num) > 0 && XSRC(num) < fullW && YSRC(num) > 0 && YSRC(num) < fullH) \
- { \
- if(!(drawCursor && InCursor(XSRC(num), YSRC(num)) && InCursorMask(XSRC(num), YSRC(num)))) \
- { \
- *(short *)DST(num) = *(short *)(src + (XSRC(num) << 1L) + YSRC(num) * src_rowbytes); \
- } \
- else \
- { \
- *(short *)DST(num) = CursorDataIs1(XSRC(num), YSRC(num)) ? 0 : 0xffff; \
- } \
- } \
- else \
- { \
- *(short *)DST(num) = 0; \
- } \
- DST(num) += 8; \
- }
-
-
- void DrawRotatedImage(float r, bool drawCursor)
- {
- short x, y, x_src, y_src;
- Ptr src, dst, next_dst;
- short src_rowbytes, dst_rowbytes;
- float r_sin, r_cos;
- short width, height;
- float rotation = (float)r;
-
- #if SCALE
- float x_scale, y_scale;
- #endif
-
- src = g_pFakeBase;
- src_rowbytes = g_ulRowBytes;
-
- next_dst = g_pBase;
- dst_rowbytes = g_ulRowBytes;
-
- rotation = -rotation;
-
- r_sin = std::sin(rotation);
- r_cos = std::cos(rotation);
-
- #if SCALE
- float scale = 0.5 - std::cos(-rotation * 2.0) / 2.0;
-
- x_scale = kXScaleMin + ((1.0 - scale) * (kXScaleMax - kXScaleMin));
- y_scale = kYScaleMin + ((scale) * (kYScaleMax - kYScaleMin));
-
- x_scale = 1.0 / x_scale;
- y_scale = 1.0 / y_scale;
- #endif
-
-
- short first = 0, last = g_ulHeight;
-
- #if HASH
- CheckHashes(&first, &last);
- #endif
-
- width = (short)(g_ulWidth >> 1);
- height = (short)(g_ulHeight >> 1);
-
- Cursor sCurs;
-
- LMGetTheCursor(&sCurs);
- Point mouse = LMGetRawMouseLocation();
-
- short cursLeft = mouse.h - sCurs.hotSpot.h, cursRight = cursLeft + 16, cursTop = mouse.v - sCurs.hotSpot.v, cursBottom = cursTop + 16;
-
- first -= height;
- last -= height;
-
- #if VECTOR
- Float4 float_trig;
- float_trig.floats[0] = float_trig.floats[3] = r_cos;
- float_trig.floats[1] = -r_sin;
- float_trig.floats[2] = r_sin;
-
- vector float trig = vec_ld(0, float_trig.floats);
-
- Float4 float_halfs;
- float_halfs.floats[0] = width;
- float_halfs.floats[2] = height;
- float_halfs.floats[1] = float_halfs.floats[3] = 0;
-
- vector float halfs = vec_ld(0, float_halfs.floats);
- #endif
-
- short fullW = g_ulWidth, fullH = g_ulHeight;
-
-
- switch(g_nDepth)
- {
- case 8:
- for(y = first; y < last; y++)
- {
- dst = next_dst;
- next_dst += dst_rowbytes;
-
- for(x = -width; x < width; x++)
- {
- x_src = (short)((float)x * r_cos - (float)y * r_sin);
- y_src = (short)((float)x * r_sin + (float)y * r_cos);
-
- #if SCALE
- x_src *= x_scale;
- y_src *= y_scale;
- #endif
-
- x_src += width;
- y_src += height;
-
- if(x_src > 0 && x_src < 2 * width && y_src > 0 && y_src < 2 * height)
- {
- if(drawCursor && InCursor(x_src, y_src) && InCursorMask(x_src, y_src))
- {
- *(char *)dst = CursorDataIs1(x_src, y_src) ? 0xff : 0;
- }
- else
- {
- *(char *)dst = *(char *)(src + x_src + y_src * src_rowbytes);
- }
- }
- else
- {
- *(char *)dst = 0xff;
- }
-
- dst += 1L;
- }
- }
- break;
- case 16:
- #if VECTOR
- // zero
- Float4 float_zero;
- float_zero.floats[0] = float_zero.floats[1] = float_zero.floats[2] = float_zero.floats[3] = 0;
- vector float zero = vec_ld(0, float_zero.floats);
-
- // y vect
- Float4 float_y_start;
- float_y_start.floats[1] = float_y_start.floats[3] = first;
- float_y_start.floats[0] = float_y_start.floats[2] = 0;
- vector float vect_y_start = vec_ld(0, float_y_start.floats);
- vector float vect_y = vect_y_start;
-
- // y increment
- Float4 float_y_inc;
- float_y_inc.floats[1] = float_y_inc.floats[3] = 1;
- float_y_inc.floats[0] = float_y_inc.floats[2] = 0;
- vector float vect_y_inc = vec_ld(0, float_y_inc.floats);
-
- // x increment
- Float4 float_x_inc;
- float_x_inc.floats[1] = float_x_inc.floats[3] = 0;
- float_x_inc.floats[0] = float_x_inc.floats[2] = 1;
- vector float vect_x_inc = vec_ld(0, float_x_inc.floats);
- // x increment * 4
- Float4 float_x_inc4;
- float_x_inc4.floats[1] = float_x_inc4.floats[3] = 0;
- float_x_inc4.floats[0] = float_x_inc4.floats[2] = 4;
- vector float vect_x_inc4 = vec_ld(0, float_x_inc4.floats);
-
- // x vect
- Float4 float_x_start;
- float_x_start.floats[1] = float_x_start.floats[3] = 0;
- float_x_start.floats[0] = float_x_start.floats[2] = -width;
- vector float vect_x_start = vec_ld(0, float_x_start.floats);
- #endif
-
- for(y = first; y < last; y++)
- {
- dst = next_dst;
- next_dst += dst_rowbytes;
-
- #if VECTOR
- Float4 float_result0;
- Float4 float_result1;
- Float4 float_result2;
- Float4 float_result3;
-
- vect_y = vec_add(vect_y_inc, vect_y);
-
- vector float vect_x0 = vect_x_start;
- vector float vect_x1 = vec_add(vect_x_inc, vect_x0);
- vector float vect_x2 = vec_add(vect_x_inc, vect_x1);
- vector float vect_x3 = vec_add(vect_x_inc, vect_x2);
-
- Ptr dst0 = dst;
- Ptr dst1 = dst + 2;
- Ptr dst2 = dst + 4;
- Ptr dst3 = dst + 6;
- #endif
-
- for(x = -width; x < width; x += XINCREMENT)
- {
- #if VECTOR
- // increment x
- vect_x0 = vec_add(vect_x_inc4, vect_x0);
- vect_x1 = vec_add(vect_x_inc4, vect_x1);
- vect_x2 = vec_add(vect_x_inc4, vect_x2);
- vect_x3 = vec_add(vect_x_inc4, vect_x3);
-
- // calculate op
- vector float op0 = vec_add(vect_x0, vect_y);
- vector float op1 = vec_add(vect_x1, vect_y);
- vector float op2 = vec_add(vect_x2, vect_y);
- vector float op3 = vec_add(vect_x3, vect_y);
-
- // calculate!
- float_result0.vec = vec_madd(op0, trig, halfs);
- float_result1.vec = vec_madd(op1, trig, halfs);
- float_result2.vec = vec_madd(op2, trig, halfs);
- float_result3.vec = vec_madd(op3, trig, halfs);
-
- // extract
- short x_src0 = (float_result0.floats[0] + float_result0.floats[1]);
- short y_src0 = (float_result0.floats[2] + float_result0.floats[3]);
- short x_src1 = (float_result1.floats[0] + float_result1.floats[1]);
- short y_src1 = (float_result1.floats[2] + float_result1.floats[3]);
- short x_src2 = (float_result2.floats[0] + float_result2.floats[1]);
- short y_src2 = (float_result2.floats[2] + float_result2.floats[3]);
- short x_src3 = (float_result3.floats[0] + float_result3.floats[1]);
- short y_src3 = (float_result3.floats[2] + float_result3.floats[3]);
-
- SetPixel(0);
- SetPixel(1);
- SetPixel(2);
- SetPixel(3);
- #else
- x_src = (short)((float)x * r_cos - (float)y * r_sin);
- y_src = (short)((float)x * r_sin + (float)y * r_cos);
- #endif
-
- #if SCALE
- #error
- x_src *= x_scale;
- y_src *= y_scale;
- #endif
-
- #if !VECTOR
- x_src += width;
- y_src += height;
-
- if(x_src > 0 && x_src < fullW && y_src > 0 && y_src < fullH)
- {
- if(drawCursor && InCursor(x_src, y_src) && InCursorMask(x_src, y_src))
- {
- *(short *)dst = CursorDataIs1(x_src, y_src) ? 0 : 0xffff;
- }
- else
- {
- *(short *)dst = *(short *)(src + (x_src << 1L) + y_src * src_rowbytes);
- }
- }
- else
- {
- *(short *)dst = 0;
- }
-
- dst += 2L;
- #endif
- }
- }
- break;
- case 32:
- for(y = first; y < last; y++)
- {
- dst = next_dst;
- next_dst += dst_rowbytes;
-
- for(x = -width; x < width; x++)
- {
- x_src = (short)((float)x * r_cos - (float)y * r_sin);
- y_src = (short)((float)x * r_sin + (float)y * r_cos);
-
- #if SCALE
- x_src *= x_scale;
- y_src *= y_scale;
- #endif
-
- x_src += width;
- y_src += height;
-
- if(x_src > 0 && x_src < 2 * width && y_src > 0 && y_src < 2 * height)
- {
- if(drawCursor && InCursor(x_src, y_src) && InCursorMask(x_src, y_src))
- {
- *(long *)dst = CursorDataIs1(x_src, y_src) ? 0 : 0xffffffff;
- }
- else
- {
- *(long *)dst = *(long *)(src + (x_src << 2L) + y_src * src_rowbytes);
- }
- }
- else
- {
- *(long *)dst = 0;
- }
-
- dst += 4L;
- }
- }
- break;
- }
- }
-
-
- #if 0
- // not used
-
- static void PlotCursor(Cursor *pCurs)
- {
- char * base = g_pFakeBase;
- Point loc = LMGetRawMouseLocation();
-
- short vOffset = loc.v - pCurs->hotSpot.v;
- short hOffset = loc.h - pCurs->hotSpot.h;
-
- for(int y = 0; y < 16; y++)
- {
- char * y_line = base + g_ulRowBytes * (vOffset + y);
-
- for(int x = 0; x < 16; x++)
- {
- if(pCurs->mask[y] & (1 << (16 - x - 1)))
- {
- Ptr x_ptr = y_line + (hOffset + x) * (unsigned long)g_nDepth / 8;
- bool on = pCurs->data[y] & (1 << (16 - x - 1));
-
- switch(g_nDepth)
- {
- case 16:
- *(short *)x_ptr = on ? 0 : 0xffff;
- break;
- case 32:
- *(unsigned long *)x_ptr = on ? 0 : 0xffffffff;
- break;
- case 8:
- *(unsigned char *)x_ptr = on ? 0xff : 0;
- break;
- }
- }
- }
- }
- }
- #endif
-
-
-
- void ResetScreen()
- {
- g_dRotation = 0.0;
- // DrawRotatedImage(g_dRotation, false);
- std::memcpy(g_pBase, g_pFakeBase, g_ulCopySize);
- }
-
-
- void SetOn()
- {
- if(g_bOn == false)
- {
- g_bOn = true;
-
- UpdateGlobals();
-
- std::memcpy(g_pFakeBase, g_pBase, g_ulCopySize);
- HideCursor();
- (**g_hPM).baseAddr = g_pFakeBase;
- }
- }
-
-
- void SetOff()
- {
- if(g_bOn)
- {
- g_bOn = false;
-
- (**g_hPM).baseAddr = g_pBase;
- ResetScreen();
- ShowCursor();
- }
- }
-
- #if HASH
-
- void CheckHashes(short *pFirst, short *pLast)
- {
- for(unsigned long y = 0; y < g_ulHeight; y++)
- {
- unsigned long ulHash = 0UL;
-
- for(unsigned long x = 0; x < g_ulWidth / sizeof(unsigned long); x++)
- {
- ulHash ^= ((unsigned long *)g_pFakeBase)[x];
- }
- if(ulHash != g_pHashes[y])
- {
- *pFirst = y;
- g_pHashes[y] = ulHash;
- goto findLast;
- }
- }
-
- // no changes
- *pFirst = *pLast = 0;
- return;
-
- findLast:
- *pLast = *pFirst;
-
- for(unsigned long y = g_ulHeight - 1; y >= *pFirst; y--)
- {
- unsigned long ulHash = 0UL;
-
- for(unsigned long x = 0; x < g_ulWidth / sizeof(unsigned long); x++)
- {
- ulHash ^= ((unsigned long *)g_pFakeBase)[x];
- }
- if(ulHash != g_pHashes[y])
- {
- *pLast = y;
- g_pHashes[y] = ulHash;
- break;
- }
- }
- }
-
- #endif
-
- void UpdateGlobals()
- {
- g_bUpdating = true;
-
- GDHandle hGD = LMGetTheGDevice();
-
- g_hPM = (**hGD).gdPMap;
-
- g_pBase = (**g_hPM).baseAddr;
-
- g_ulHeight = (**g_hPM).bounds.bottom - (**g_hPM).bounds.top;
- g_ulWidth = (**g_hPM).bounds.right - (**g_hPM).bounds.left;
- g_ulRowBytes = ((**g_hPM).rowBytes & 0x00007fff);
- g_ulCopySize = g_ulHeight * g_ulRowBytes;
-
- g_nDepth = (**g_hPM).pixelSize;
-
- g_bUpdating = false;
- }
-